package com.system.core.utils;

import org.apache.commons.lang3.StringUtils;

import java.util.regex.Pattern;

/**
 * @Description:
 * @Author: kaxiaofei
 * @Date: 2020/7/13
 * @Version: v1.0
 */
public class ValidatorUtil {

    /**
     * 判断是否不为空
     *
     * @param str
     * @param fieldName
     * @throws IllegalArgumentException
     */
    public static void isNotEmpty(String str, String fieldName) throws IllegalArgumentException {
        if (StringUtils.isEmpty(str)) {
            throw new IllegalArgumentException(fieldName + " cannot be null or empty!");
        }
    }

    /**
     * 判断是否不为NULL
     *
     * @param object
     * @param fieldName
     * @throws IllegalArgumentException
     */
    public static void isNotNull(Object object, String fieldName) throws IllegalArgumentException {
        if (object == null) {
            throw new IllegalArgumentException(fieldName + " cannot be null!");
        }
    }

    /**
     * 判断是否数字（不能为空，且大于0）
     * @param number
     * @throws IllegalArgumentException
     */
    public static void isNumber(Number number) throws IllegalArgumentException {
        isNotNull(number, "number");
        isTrue(number.doubleValue() > 0.0, "Number error!");
    }

    /**
     * 判断是否为true
     *
     * @param b
     * @param message
     * @throws IllegalArgumentException
     */
    public static void isTrue(boolean b, String message) throws IllegalArgumentException {
        if (!b) {
            throw new IllegalArgumentException(message);
        }
    }

    /**
     * 判断是否为false
     *
     * @param b
     * @param message
     * @throws IllegalArgumentException
     */
    public static void isFalse(boolean b, String message) throws IllegalArgumentException {
        if (b) {
            throw new IllegalArgumentException(message);
        }
    }

    /**
     * #校验是否手机号
     *
     * @param mobile
     * @throws IllegalArgumentException
     */
    public static void isMobile(String mobile) throws IllegalArgumentException {
        isNotEmpty(mobile, "mobile");
        isTrue(Pattern.matches(CommonRegexpPattern.REGEX_MOBILE, mobile), "Cell phone number wrong!");
    }

    /**
     * #校验银行卡是否正确
     *
     * @param bankAccountNo
     * @throws IllegalArgumentException
     */
    public static void isBankAccountNo(String bankAccountNo) throws IllegalArgumentException {
        isNotEmpty(bankAccountNo, "bankAccountNo");
        String errorMsg = "Bank card number wrong!";
        if (StringUtils.isEmpty(bankAccountNo) || bankAccountNo.length() < 15 ||
                bankAccountNo.length() > 19 || !bankAccountNo.matches("\\d+")) {
            throw new IllegalArgumentException(errorMsg);
        }

        //校验最后一位校验码
        char bit = getBankCardCheckCode(bankAccountNo.substring(0, bankAccountNo.length() - 1));
        if (bankAccountNo.charAt(bankAccountNo.length() - 1) != bit) {
            throw new IllegalArgumentException(errorMsg);
        }
    }

    /**
     * #校验身份证
     *
     * @param idCardNo
     * @return
     */
    public static void isIdCard(String idCardNo) throws IllegalArgumentException {
        isNotEmpty(idCardNo, "idCard");
        String errorMsg = "ID card number wrong!";
        isMatches(idCardNo, CommonRegexpPattern.REGEX_ID_CARD, errorMsg);
        if (!cardCodeVerify(idCardNo)) {
            throw new IllegalArgumentException(errorMsg);
        }
    }

    /**
     * 判断是否满足某个表达式
     *
     * @param value
     * @param pattern
     * @param message
     */
    public static void isMatches(String value, String pattern, String message) {
        isTrue(Pattern.matches(pattern, value), message);
    }

    /**
     * #从不含校验位的银行卡卡号采用 Luhm校验算法获得校验位
     *
     * @param bankAccountNo
     * @return
     */
    private static char getBankCardCheckCode(String bankAccountNo) {
        char[] chs = bankAccountNo.trim().toCharArray();
        int luhmSum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }

    /**
     * #校验身份证的最后一位
     *
     * @param cardcode
     * @return
     */
    private static boolean cardCodeVerify(String cardcode) {
        int i = 0;
        String r = "error";
        String lastNumber = "";

        i += Integer.parseInt(cardcode.substring(0, 1)) * 7;
        i += Integer.parseInt(cardcode.substring(1, 2)) * 9;
        i += Integer.parseInt(cardcode.substring(2, 3)) * 10;
        i += Integer.parseInt(cardcode.substring(3, 4)) * 5;
        i += Integer.parseInt(cardcode.substring(4, 5)) * 8;
        i += Integer.parseInt(cardcode.substring(5, 6)) * 4;
        i += Integer.parseInt(cardcode.substring(6, 7)) * 2;
        i += Integer.parseInt(cardcode.substring(7, 8)) * 1;
        i += Integer.parseInt(cardcode.substring(8, 9)) * 6;
        i += Integer.parseInt(cardcode.substring(9, 10)) * 3;
        i += Integer.parseInt(cardcode.substring(10, 11)) * 7;
        i += Integer.parseInt(cardcode.substring(11, 12)) * 9;
        i += Integer.parseInt(cardcode.substring(12, 13)) * 10;
        i += Integer.parseInt(cardcode.substring(13, 14)) * 5;
        i += Integer.parseInt(cardcode.substring(14, 15)) * 8;
        i += Integer.parseInt(cardcode.substring(15, 16)) * 4;
        i += Integer.parseInt(cardcode.substring(16, 17)) * 2;
        i = i % 11;
        lastNumber = cardcode.substring(17, 18);
        if (i == 0) {
            r = "1";
        }
        if (i == 1) {
            r = "0";
        }
        if (i == 2) {
            r = "x";
        }
        if (i == 3) {
            r = "9";
        }
        if (i == 4) {
            r = "8";
        }
        if (i == 5) {
            r = "7";
        }
        if (i == 6) {
            r = "6";
        }
        if (i == 7) {
            r = "5";
        }
        if (i == 8) {
            r = "4";
        }
        if (i == 9) {
            r = "3";
        }
        if (i == 10) {
            r = "2";
        }
        if (r.equals(lastNumber.toLowerCase())) {
            return true;
        }
        return false;
    }
}
